<?php
namespace app\service;
use app\model\User;
use think\exception\ValidateException;
use think\facade\Session;

class UserService extends BaseService
{
    const USER_FREEZE = 1;//账号冻结
    const USER_VERIFY_PASSWORD_FAILED = 2;//用户密码不匹配
    const USER_VERIFY_USERNAME_FAILED = 3;//用户名不匹配
    const  USER_VERIFY_SUCCESS = 4; //验证成功
    const  USER_VERIFY_LOGIN_TIMES = 5; //超过登录次数
    const  ALLOW_LOGIN_TIMES = 5; //超过5次就禁用
    const ERROR = [
        self::USER_FREEZE => "账号冻结",
        self::USER_VERIFY_PASSWORD_FAILED => "用户密码不匹配",
        self::USER_VERIFY_USERNAME_FAILED => "用户名错误",
        self::USER_VERIFY_SUCCESS => "验证成功",
        self::USER_VERIFY_LOGIN_TIMES => "超过登录次数",
        self::ALLOW_LOGIN_TIMES => "登录错误次数超限"
    ];

    protected function setModel(): string
    {
        return User::class;
    }

    /**
     * 登录
     * @param $username
     * @param $password
     * @return int|bool
     */
    public function login($username, $password): int|bool
    {
        $res = $this->getOne(["username" => $username]);
        if (empty($res)) {
            throw new ValidateException(self::ERROR[self::USER_VERIFY_USERNAME_FAILED]);
        }
        if ($res->login_error_times >= self::ALLOW_LOGIN_TIMES) {
            $update_data = ["id" => $res["id"], "status" => self::STATE_DENY];
            $this->save($update_data);
            throw new ValidateException(self::ERROR[self::USER_VERIFY_LOGIN_TIMES]);
        }
        if (!password_verify($password, $res->password)) {
            throw new ValidateException(self::ERROR[self::USER_VERIFY_PASSWORD_FAILED]);
        }

        if ($res->status == self::STATE_DENY) {
            throw new ValidateException(self::ERROR[self::USER_FREEZE]);
        }
        Session::set("uid", $res->id);
        Session::set("user", ["username" => $res->username, "nickname" => $res->nickname, "headimg" => $res->headimg]);
        return self::USER_VERIFY_SUCCESS;
    }

    /**
     * 更新用户信息
     * @param $username
     * @param $ip
     * @param $times
     * @return bool
     */
    public function updateUserByUsername($username, $login, $ip)
    {
        $user = $this->getOne(["username" => $username]);
        $user->login_at = date("Y-m-d H:i:s");
        $user->login_ip = $ip;
        $user->inc('login_error_times', 1);
        if ($login) {
            $user->login_error_times = 0;
        }
        return $user->save();
    }

    /**
     * 修改密码
     * @param $params
     * @return mixed
     */
    public function savePasswd($params)
    {
        $update = [
            "id" => $params["id"],
            "password" => $params["password"],
        ];
        return $this->save($update);
    }

    /**
     * 添加保存后台用户同时分配角色
     * @param $params
     * @return mixed
     */
    public function saveAll($params)
    {
        if (!empty($params["id"])) {
            $model = $this->get($params["id"]);
            if (!empty($params["role"])) {
                $model->roles()->detach();
            }
        } else {
            $model = $this->getModel();
            $model->username = $params["username"];
        }
        $model->nickname = $params["nickname"];
        if (!empty($params["contact_phone"])) {
            $model->contact_phone = $params["contact_phone"];
        }
        if (!empty($params["contact_qq"])) {
            $model->contact_qq = $params["contact_phone"];
        }
        if (!empty($params["remark"])) {
            $model->remark = $params["remark"];
        }
        if (!empty($params["contact_email"])) {
            $model->contact_email = $params["contact_email"];
        }
        if (!empty($params["headimg"])) {
            $model->headimg = $params["headimg"];
        }
        $res = $model->save();
        if (!empty($params["role"])) {
            $res = $model->roles()->saveAll($params["role"]);
        }
        return $res;
    }

    /**
     * 设置状态，同时清理错误次数
     * @param $id
     * @param $status
     * @return false
     */
    public function setStatus($id, $status)
    {
        $user = $this->get($id);
        $user->status = $status;
        $user->login_error_times = 0;
        return $user->save();
    }
}